<?php
/**
 * Created by PhpStorm.
 * Notes:亿奇达对接接口
 * User: ymzhang
 * Date: 2022/06/29
 * Time: 16:40
 */

namespace  api\channel\coupon;

use api\channel\coupon\strategy\Local;
use app\common\service\order\coupon_order\coupon\CouponOrderBuild;
use app\event\SupplierNotifyFail;
use app\event\SupplierNotifySuccess;
use app\listener\notify\CouponButtFail;
use app\model\BaseSupplier;
use app\model\CouponOrder;
use api\channel\coupon\strategy\Test;
use app\model\CouponProductChannel;
use think\Model;


/**
 * 亿奇达权限
 * 文档地址：https://www.showdoc.com.cn/yiqida/7223557808701827
 */
class YiQiDaHandler extends BaseHandler
{
    /**
     * 账号
     * @var string $userName
     */
    private $userName;

    /**
     * 状态码
     * @var array $codeMsg
     */
    protected $codeMsg = [
        '200'   =>	'请求成功',
        '403'   =>	'权限不足',
        '404'   =>	'找不到资源',
        '405'   =>	'参数错误',
        '406'   =>	'签名错误',
        '411'   =>	'未登录',
        '412'   =>	'登录失效',
        '500'   =>	'未经处理的异常',
        '506'   =>	'失败,此错误需要看msg里面的信息',
        '508'   =>	'操作频繁,重新提交订单',
        '509'   =>	'访问设备已失效',
        '510'   =>	'访问设备已经封停',
        '511'   =>	'设备状态异常',
        '513'   =>	'系统更新升级中',
        '55'    =>	'系统报错',
        '-1001' =>	'API登录失败',
        '1001'  =>	'外部订单号重复',
        '1002'  =>	'买家进货高于卖价，用于防止溢价亏损',
        '1003'  =>	'商品已下架',
        '1004'  =>	'商品编号不存在',
        '1005'  =>	'外部单号限制，如超长',
        '1006'  =>	'备注限制，如超长',
        '1007'  =>	'回调地址限制，如超长',
        '1008'  =>	'用户类型错误',
        '1009'  =>	'参数模板限制，如没按模板传参',
        '1010'  =>	'购买数量限购，如超出购买限制',
    ];

    /**
     * 头部
     * @var array $header
     */
    protected $header = [
        'Content-Type: application/json;charset=UTF-8',
    ];

    /**
     * 账号
     * @var string $priceSyncUrl
     */
    //商品信息异步通知url(主要是调价)
    protected $priceSyncUrl;

    //充值类型
    const VIRTUALDELIVERY_ZC = 3; //官方直充
    const VIRTUALDELIVERY_KM = 6; //卡密

    //商品状态
    const PRODUCT_STATUS_ACTIVE = 1;      //1上架 2下架 3删除 4维护
    const PRODUCT_STATUS_CLOSE  = 2;      //1上架 2下架 3删除 4维护
    const PRODUCT_STATUS_DELETE = 3;      //1上架 2下架 3删除 4维护
    const PRODUCT_STATUS_FIXED  = 4;      //1上架 2下架 3删除 4维护


    //下单状态
    const ORDER_STATUS_WAIT_PAY = 1;            //等待支付，下一时刻会变成2
    const ORDER_STATUS_WAIT_DELIVER_GOODS = 2;  //等待发货，等待处理
    const ORDER_STATUS_SHIPPED = 3;             //已发货，物流派送中
    const ORDER_STATUS_SUCCESS = 4;             //交易成功，订单完成，虚拟充值商品订单成功为该状态
    const ORDER_STATUS_CANCEL = 5;              //交易取消，订单失败，虚拟充值商品订单失败为该状态
    const ORDER_STATUS_PROCESSING = 6;          //处理中，正在处理


    /**
     *初始化构造函数
     */
    public function __construct()
    {
        //供应商参数
        $info = BaseSupplier::where('code', BaseSupplier::CODE_YIQIDA)
            ->where('serv_type',PRODUCT_COUPON_SERV)
            ->cache(BaseSupplier::CODE_YIQIDA.PRODUCT_COUPON_SERV,'3600')
            ->find();
        if (!$info) {
            return web_request([],false, 901, '渠道商配置错误');
        }
        $this->supplier = $info;
        $config = is_string($info->api_config) ? json_decode($info->api_config, true) : $info->api_config;
        $this->userName = trim($config['userName']);
        $this->apiKey = trim($config['apikey']);
        $this->bestUrl = trim($config['bestUrl']);
        //回调地址
        $this->notifyUrl = env('app.api_url') . '/api/notify_v2/yiqidaNotify/supplierId/' . $info['id'];

        //商品信息异步通知url
        $this->priceSyncUrl = env('app.api_url') . '/api/notify_v2/yiQiDaPriceSync';
    }

    /**
     * Notes:获取供应商配置的用户名
     * User: ymzhang
     * Date: 2022/06/29
     * Time: 13:50
     * @return string
     */
    public function getUserName()
    {
        return $this->userName;
    }

    /**
     * Notes:查询商品分组列表查询
     * User: ymzhang
     * Date: 2022/06/29
     * Time: 17:40
     * @return array
     */
    public function getCatalogList()
    {
        $timestamp = msectime();
        $sign = $this->generateSign($timestamp, $this->getKey());
        $url = $this->getBaseUrl().'api/UserCommdity/GetCatalogList?timestamp='.$timestamp.'&userName='.$this->getUserName().'&sign='.$sign;
        $res = curlPost($url, '', $this->header);
        if (empty($res)) {
            return web_request([],false, 404, $this->getMsg('404'));
        }
        $res = json_decode($res,true);
        $data = [
            'cateList'    => $res['data'],
            'totalNumber' => $res['sum'],
        ];
        return web_request($data,true, 200, $this->getMsg('200'));
    }

    /**
     * Notes:查询商品列表
     * User: ymzhang
     * Date: 2022/06/29
     * Time: 18:10
     * @param int $page 页码
     * @param int  $catalogId 分组id
     * @param int $size 每页展示数量 默认60
     * @return array
     */
    public function getCommodityList(int $page, int $catalogId = 0, int $size = 60)
    {
        if ( empty($page) || !is_numeric($page) || $page < 1) {
            return web_request([],false, '', '页码参数错误');
        }
        $timestamp = msectime();
        $params = [
            'page' => $page??1,
            'size' => $size,
            'catalogId' => $catalogId??'',
        ];
        $params = json_encode($params,JSON_UNESCAPED_UNICODE);
        $sign = $this->generateSign($timestamp, $params, $this->getKey());
        $url = $this->getBaseUrl().'api/UserCommdity/GetCommodityList?timestamp='.$timestamp.'&userName='.$this->getUserName().'&sign='.$sign;
        $res = curlPost($url, $params, $this->header);
        if (empty($res)) {
            return web_request([],false, 404, $this->getMsg('404'));
        }
        $res = json_decode($res,true);
        $data = [
            'commodityList' => $res['data'],
            'total' => $res['sum']
        ];
        return web_request($data,true, 200, $this->getMsg('200'));
    }

    /**
     * Notes:获取商品详情信息
     * User: ymzhang
     * Date: 2022/06/29
     * Time: 17:10
     * @param string $order_id
     * @return array
     */
    public function getCommodityInfo(string $order_id)
    {
        if (empty($order_id)) {
            return web_request([],false, 1004, '商品编号不能为空');
        }
//        $info = CouponOrder::where('order_id', $order_id)->findOrEmpty();
//        if ($info->isEmpty()) {
//            return web_request([],false, 1004, $this->getMsg('1004'));
//        }
        $timestamp = msectime();
        $params = [
            'id' => $order_id,
        ];
        $params = json_encode($params,JSON_UNESCAPED_UNICODE);
        $sign = $this->generateSign($timestamp, $params, $this->getKey());
        $url = $this->getBaseUrl().'api/UserCommdity/GetCommodityInfo?timestamp='.$timestamp.'&userName='.$this->getUserName().'&sign='.$sign;
        $res = curlPost($url, $params, $this->header);
        $res = json_decode($res,true);
        if ($res['code'] != 200) {
            return web_request([],false, $res['code'], $this->getMsg($res['code']));
        }
        return web_request($res['data'],true, 200, $this->getMsg('200'));
    }

    /**
     * Notes:查询余额
     * User: ymzhang
     * Date: 2022/06/30
     * Time: 11:10
     * @return array
     */
    public function getMemberInfo(){
        $timestamp = msectime();
        $sign = $this->generateSign($timestamp, $this->getKey());
        $url = $this->getBaseUrl().'api/UserInfo/GetMemberInfo?timestamp='.$timestamp.'&userName='.$this->getUserName().'&sign='.$sign;
        $res = curlPost($url, '', $this->header);
        if (empty($res)) {
            return web_request([],false, 404, '查询失败');
        }
        $res = json_decode($res,true);
        if ($res['code'] != 200) {
            return web_request([],false, $res['code'], $this->getMsg($res['code']));
        }
        return web_request($res['data'],true, 200, $this->getMsg('200'));
    }

    /**
     * Notes:提交新订单
     * User: ymzhang
     * Date: 2022/06/29
     * Time: 18:35
     * @param CouponOrder $couponOrder
     */
    public function createOrder(CouponOrder $couponOrder)
    {
        //如果不是生产环境
        if (!isProd()){
            if (isLocal()) {
                return false;
            }
            /*if (isTesting()) {
                if (($couponOrder->couponProductChannel)->cost_price > 100) {
                    return false;
                }
            }*/
        }
        //实时验证价格是否一样,不一致走退款流程
        $res = $this->getCommodityInfo($couponOrder->couponProductChannel->origin_id);
        if ((!$res['status']) || $res['code'] != 200 || empty($res['data'])) {
            return web_request([],false, 1001, '下单失败');
        }
        $new_cost_price = yuan2fen($res['data']['price']);
        $old_cost_price = $couponOrder->couponProductChannel->cost_price;
        if ( $new_cost_price != $old_cost_price) {
            //更新当前系统的价格
            /**
             * @var CouponProductChannel $couponProductChannel
             */
            /*if ($couponOrder->couponProductChannel->cost_price != yuan2fen($res['data']['price'])){
                $couponProductChannel->cost_price = yuan2fen($res['data']['price']);
                $couponProductChannel->save();

                $newCouponOrder = new CouponOrder();
                $newCouponOrder->quote_id = $couponOrder->quote_id;
                $newCouponOrder->agent_id = $couponOrder->agent_id;

                $buildService = new CouponOrderBuild($newCouponOrder);

                //如果支付金额小于结算金额则不再进行轮训
                if ($couponOrder->pay_amount < $buildService->settle_price) {
                    (new CouponButtFail())->refundStatus($couponOrder);
                    return true;
                }
            }*/
            //1.将本系统中对应的商品成本价格进行修改
            $couponProductChannel->cost_price = $new_cost_price;
            $couponProductChannel->save();

            //todo 情况一供应商那边涨价了，直接返回下单失败，走退款流程
            if ($new_cost_price > $old_cost_price) {
                //1.下单失败，走退款流程
                (new CouponButtFail())->refundStatus($couponOrder);
                //event(new SupplierNotifyFail($couponOrder));
                return web_request([],false, 1001, '下单失败，系统成本价和供应商成本价不一致');
            }
            //todo 情况二、当商品价格下调时，平台成本减少，利润增加，可以继续到供应商下单
            if ($new_cost_price < $old_cost_price) {
                //记录下最新的供应商结算价
                $couponOrder->new_supplier_price = $new_cost_price;
                $couponOrder->save();
            }
        }

        $params = [
            'commodityId'       =>      $couponOrder->couponProductChannel->origin_id, //coupon_product_channel.origin_id渠道商品编号
            'external_orderno'  =>      $couponOrder->order_id,            //coupon_order.order_id               平台订单号
            'buyCount'          =>      1,                                 //coupon_order表没有数量                设计表中暂时没有数量字段
            'remark'            =>      $couponOrder->remark,              //coupon_order.remark                 备注
            'callbackUrl'       =>      $this->getNotifyUrl(),             //回调地址
            'externalSellPrice' =>      fen2yuan($couponOrder->pay_amount),// 单位是元 coupon_order.amount         不确定是否传这个字段
            'template'          =>      [urlencode($couponOrder->account)],//充值账号 coupon_order.account
        ];
        $timestamp = msectime();
        $params = json_encode($params,JSON_UNESCAPED_UNICODE);
        $sign = $this->generateSign($timestamp, $params, $this->getKey());
        $url = $this->getBaseUrl().'api/UserOrder/CreateOrder?timestamp='.$timestamp.'&userName='.$this->getUserName().'&sign='.$sign;
        $res = curlPost($url, $params, $this->header);
        if (empty($res)) {
            return web_request([],false, 1001, '下单失败');
        }
        $res = json_decode($res,true);

        if (empty($res['code'])) {
            return web_request([],false, $res['code'], $this->getMsg($res['code']));
        }

        if ($res['code'] == 506){
            event(new SupplierNotifyFail($couponOrder)); //余额不足退款
            return web_request([],false, $res['code'], $this->getMsg($res['code']));
        }
        if ($res['code'] != 200) {
            //支付失败事件
            //event(new SupplierNotifyFail($couponOrder));
            return web_request([],false, $res['code'], $this->getMsg($res['code']));
        }


        $couponOrder->supplier_status = CouponOrder::SUPPLIER_STATUS_SUBMIT;
        $couponOrder->status = CouponOrder::C_STATUS_SUBMIT;
        $couponOrder->save();
        //支付成功事件
        //event(new SupplierNotifySuccess($couponOrder));
        return web_request($res['data'],true, 200, $this->getMsg('200'));
    }

    /**
     * Notes:异步通知接口,只做数据的校验，不做具体业务逻辑的处理
     * User: ymzhang
     * Date: 2022/06/30
     * Time: 10:35
     * @param string $sign 加密字符串
     * @param string $params body传的参数
     * @return array
     */
    public function sycNotify($sign, $params)
    {
        //try {
            if(empty($sign) || empty($params)) {
                return web_request([],false, 405, $this->getMsg('405'));
            }
            //校验sign是否正确
            if($sign != $this->generateSign($params, $this->getKey())) {
                return web_request([],false, 406, $this->getMsg('406'));
            }
            return web_request(json_decode($params,true),true, 200, '验证成功');
//        } catch (\Exception $e) {
//            return web_request([],false, 405, $e->getMessage());
//        }
    }

    /**
     * Notes:查询进货订单状态
     * User: ymzhang
     * Date: 2022/06/30
     * Time: 11:00
     * @param string $order_id                   平台订单号
     * @param string $supplier_order_sn          亿奇达订单号
     * @return array
     */
    public function queryOrder($order_id, $supplier_order_sn)
    {
        if(empty($order_id) || empty($supplier_order_sn)) {
            return web_request([],false, 405, '平台订单号和亿奇达订单号不能为空');
        }
        $timestamp = msectime();
        $params = [
            'external_orderno' => $order_id,
            'orderNo'          => $supplier_order_sn,
            'orderTime'        => '10',
        ];
        $params = json_encode($params,JSON_UNESCAPED_UNICODE);
        $sign = $this->generateSign($timestamp, $params, $this->getKey());
        $url = $this->getBaseUrl().'api/UserOrder/QueryOrderModel?timestamp='.$timestamp.'&userName='.$this->getUserName().'&sign='.$sign;
        $res = curlPost($url, json_encode($params,JSON_UNESCAPED_UNICODE), $this->header);
        if (empty($res)) {
            return web_request([],false, 1001, '查询订单状态失败');
        }
        $res = json_decode($res,true);
        if ($res['code'] != 200) {
            return web_request([],false, $res['code'], $this->getMsg($res['code']));
        }
        return web_request($res['data'],true, 200, $this->getMsg('200'));
    }

    /**
     * Notes:上架供应商信息
     * User: ymzhang
     * Date: 2022/10/20
     * Time: 09:30
     * @return string
     */
    public function getSupplierInfo()
    {
        return $this->supplier;
    }
}